package org.king.controller;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Pattern;
import org.king.exception.LoginErrorException;
import org.king.exception.RegisterErrorException;
import org.king.pojo.RestBean;
import org.king.pojo.dto.account.ResetPasswordConfirmDTO;
import org.king.pojo.dto.account.ResetPasswordDTO;
import org.king.pojo.dto.account.AccountLoginDTO;
import org.king.pojo.entity.Account;
import org.king.pojo.dto.account.AccountRegisterByEmailDTO;
import org.king.pojo.vo.AuthorizeVO;
import org.king.service.AccountService;
import org.king.util.JwtUtil;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.function.Supplier;

@Validated
@RestController
@RequestMapping("/account")
public class AccountController {
    @Resource
    private AccountService accountService;
    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private PasswordEncoder passwordEncoder;

    @GetMapping("/ask-code")
    public RestBean<Void> askVerifyCode(@RequestParam("email") @Email String email,
                                        @RequestParam("type") @Pattern(regexp = "(register|reset)") String type,
                                        HttpServletRequest request) {
        String message = accountService.registerEmailVerifyCode(type, email, request.getRemoteAddr());
        if(message == null) return RestBean.success();
        else return RestBean.failure(400, message);
    }

    @PostMapping("/login")
    public RestBean<AuthorizeVO> login(@RequestBody @Valid AccountLoginDTO loginDTO) {
        String username = loginDTO.getUsername();
        String password = loginDTO.getPassword();
        //获取数据库用户
        Account account = accountService.getUserByEmailOrUsername(username);
        if (account == null || !passwordEncoder.matches(password, account.getPassword())) {
            throw new LoginErrorException();
        }
        //用户信息
        User user = new User(account.getUsername(), account.getPassword(), List.of());
        String token = jwtUtil.createJwt(user, account.getId(), account.getUsername());

        AuthorizeVO vo = AuthorizeVO.builder()
                .username(username)
                .role(account.getRole())
                .token(token)
                .expire(jwtUtil.expireTime())
                .build();
        return RestBean.success(vo);
    }

    @PostMapping("/register")
    public RestBean<Void> register(@RequestBody @Valid AccountRegisterByEmailDTO dto){
        String message = accountService.registerEmailAccount(dto);
        if(message != null){
            throw new RegisterErrorException(message);
        }
        return RestBean.success();
    }

    @PostMapping("/reset-confirm")
    public RestBean<Void> resetConfirm(@RequestBody @Valid ResetPasswordConfirmDTO dto){
        String message = accountService.resetConfirmCode(dto);
        if(message != null){
            throw new RegisterErrorException(message);
        }
        return RestBean.success();
    }

    @PostMapping("/reset-password")
    public RestBean<Void> resetPassword(@RequestBody @Valid ResetPasswordDTO dto){
        String message = accountService.resetPassword(dto);
        if(message != null){
            throw new RegisterErrorException(message);
        }
        return RestBean.success();
    }

    private RestBean<Void> messageHandle(Supplier<String> action){
        String message = action.get();
        return message==null ? RestBean.success() : RestBean.failure(400, message);
    }
}
